using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Threading;
using FluentAvalonia.UI.Controls;
using FluentAvalonia.UI.Windowing;
using MusicFluent.Models;
using MusicFluent.MusicViews;
using MusicFluent.Pages;
using MusicFluent.ViewModels;
using MusicFluent.ViewModels.Pages;
using NetEasyMusic.Lib.Data;
using NetEasyMusic.Lib.Details;
using NetEasyMusic.Lib.Models;
using NetEasyMusic.Lib.Operations;

namespace MusicFluent.Views;

public partial class MainWindow : AppWindow
{
    private Dictionary<string, PageModelBase> Stack { get; }
    private WindowNotificationManager? _manager;

    public MainWindow()
    {
        Stack = new Dictionary<string, PageModelBase>
        {
            { "Home", new HomeViewModel() },
            { "Find", new FindViewModel() },
            { "Video", new VideoViewModel() },
            { "My", new MyViewModel() },
            { "Setting", new SettingViewModel() }
        };

        var model = CookieStatic.Read();
        Cookie = model?.Cookie ?? "";

        InitializeComponent();

        SplashScreen = new MainAppSplashScreen("MusicFluent", Init);
        TitleBar.ExtendsContentIntoTitleBar = true;
        TitleBar.TitleBarHitTestType = TitleBarHitTestType.Complex;

        FrameView.IsNavigationStackEnabled = true;
        FrameView.NavigationPageFactory = new NavigationFactory();
    }

    #region Item

    private void ItemInvoked(object? sender, NavigationViewItemInvokedEventArgs e)
    {
        if (e.InvokedItemContainer.Tag is not string s) return;
        if (string.IsNullOrEmpty(s)) return;
        Navigate(s);
    }

    private void Navigate(string page)
    {
        if (string.IsNullOrEmpty(page)) return;
        Navigate(Stack[page]);
    }

    public void Navigate(object context)
    {
        FrameView.NavigateFromObject(context);
    }

    private void BackClick(object? sender, RoutedEventArgs e)
    {
        FrameView.GoBack();
    }

    #endregion

    #region Login & Init

    public string Cookie { get; private set; }

    public async void Login(string cookie)
    {
        if (await Init(cookie))
            Navigate("Home");
        else
            Navigate(new LoginView());
    }

    public void Login(string cookie, UserModel user)
    {
        Cookie = cookie;
        var userApp = new User(cookie);
        DataContext = new MainWindowViewModel(cookie);

        var find = Stack["Find"] as FindViewModel;
        find!.Playlist = new Playlist(cookie);

        var my = Stack["My"] as MyViewModel;
        my!.User = user;
        my.UserApp = userApp;

        var home = Stack["Home"] as HomeViewModel;
        home!.Personalized = new Personalized(cookie);

        Navigate("Home");
    }

    private async Task<bool> Init(string? cookie)
    {
        if (string.IsNullOrEmpty(cookie)) return false;
        var userApp = new User(cookie);
        Dispatcher.UIThread.Post(() => DataContext = new MainWindowViewModel(cookie));

        var user = await userApp.GetUserInfo();
        if (user == null) return false;
        Cookie = cookie;

        var find = Stack["Find"] as FindViewModel;
        find!.Playlist = new Playlist(cookie);

        var my = Stack["My"] as MyViewModel;
        my!.User = user;
        my.UserApp = userApp;

        var home = Stack["Home"] as HomeViewModel;
        home!.Personalized = new Personalized(cookie);

        var video = Stack["Video"] as VideoViewModel;
        video!.Video = new Video(cookie);

        return true;
    }

    public void Logout()
    {
        Cookie = "";
        Navigate(new LoginView());
    }

    #endregion

    #region Window Init

    private async void Init()
    {
        if (await Init(Cookie))
        {
            Dispatcher.UIThread.Post(() => FrameView.NavigateFromObject(Stack["Home"]));
        }
        else
        {
            Dispatcher.UIThread.Post(() => FrameView.NavigateFromObject(new LoginView()));
        }
    }

    protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
    {
        base.OnApplyTemplate(e);
        _manager = new WindowNotificationManager(this) { MaxItems = 3, Position = NotificationPosition.BottomRight };
    }

    #endregion

    #region Event

    private void ValueReleased(object? sender, RangeBaseValueChangedEventArgs e)
    {
        if (FrameView.Content is not PlayMusicView view) return;
        view.LyricScroll(view.Time * e.NewValue);
    }


    private void SongDataChanged(object? sender, EventArgs e)
    {
        if (sender is not Control control) return;
        if (control.DataContext is not SongModel song) return;
        if (DataContext is not MainWindowViewModel model) return;
        model.PlayingMusic = song;
        if (!string.IsNullOrEmpty(song.PicUrl))
            MusicImage.Source = $"{song.PicUrl}?param=80y80";

        MusicNameBlock.Text = song.Name;
        var artist = song.Artists.FirstOrDefault();
        if (artist != null)
        {
            ArtistButton.Content = song.Artists.FirstOrDefault();
            ArtistButton.IsVisible = true;
        }
        else
        {
            ArtistButton.IsVisible = false;
        }

        TotalLenBlock.Text = int.Parse(song.Time).ToTimeString();
        Grid.IsVisible = true;
    }

    private void NextClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel model) return;
        model.Next();
        SongPanel.DataContext = model.PlayingMusic;
    }

    private void ListClick(object? sender, RoutedEventArgs e)
    {
        if (DataContext is not MainWindowViewModel model) return;
        var view = new PlaylistView(new PlaylistDetailModel { Musics = model.List, Name = "播放列表" });
        Navigate(view);
    }

    private void MusicImageTapped(object? sender, TappedEventArgs e)
    {
        if (sender is not Control control) return;
        if (control.DataContext is not SongModel song) return;
        var view = new PlayMusicView(song, Cookie);
        Navigate(view);
    }

    private void SearchKeyUp(object? sender, KeyEventArgs e)
    {
        if (e.Key != Key.Enter) return;
        if (sender is not AutoCompleteBox box) return;
        if (string.IsNullOrEmpty(box.Text)) return;
        var view = new SearchView(box.Text);
        Navigate(view);
    }

    #endregion

    #region Func

    public void ChangeTime(double d)
    {
        if (DataContext is MainWindowViewModel model)
            model.PosChange((float)d);
    }

    public void NotificationShow(string title, string message)
    {
        _manager?.Show(new Notification(title, message));
    }

    public void TaskShow()
    {
        TaskBar.IsVisible = !TaskBar.IsVisible;
    }

    #endregion

    private void ArtistClick(object? sender, RoutedEventArgs e)
    {
        if (sender is not Button b) return;
        if (b.Content is not ArtistModel model) return;
        var artist = new ArtistView(model, Cookie);
        Navigate(artist);
    }
}